﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using ERTesting.Dao;
using GalaSoft.MvvmLight;
using ERTesting.Model.Config;
using GalaSoft.MvvmLight.Command;

namespace ERTesting.Gui.ViewModel.Config
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class SheetConfigViewModel : ViewModelBase
    {
 
        #region Private Members
        
        private readonly ITestConfigService _configService;


        /// <summary>
        /// The <see cref="Scenarios" /> property's name.
        /// </summary>
        public const string ScenariosPropertyName = "Scenarios";

        private ObservableCollection<ScenarioViewModel> _scenarios = new ObservableCollection<ScenarioViewModel>();
        private bool _lazyLoaded = false;

        #endregion Private Members


        #region Public Properties

        public SheetConfig Config
        {
            get;
            private set;
        }

        public string DisplayName
        {
            get
            {
                return Config.Name;
            }
            set { Config.Name = value;
            RaisePropertyChanged(DisplayNameProperty);}
        }


        /// <summary>
        /// The <see cref="IsCreatedByMacro" /> property's name.
        /// </summary>
        public const string IsCreatedByMacroPropertyName = "IsCreatedByMacro";


        /// <summary>
        /// Gets the IsCreatedByMacro property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsCreatedByMacro
        {
            get { return Config.Mode == SpreadsheetModeEnum.DoNothing; }

            set
            {
                Config.Mode = SpreadsheetModeEnum.DoNothing;

                // Update bindings, no broadcast
                RaisePropertyChanged(IsCreatedByMacroPropertyName);
                RaisePropertyChanged(IsNewWorkbookPropertyName);
                RaisePropertyChanged(IsExistingWorkbookPropertyName);

            }
        }

        /// <summary>
        /// The <see cref="IsNewWorkbook" /> property's name.
        /// </summary>
        public const string IsNewWorkbookPropertyName = "IsNewWorkbook";

        /// <summary>
        /// Gets the IsNewWorkbook property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsNewWorkbook
        {
            get
            {
                return Config.Mode == SpreadsheetModeEnum.NewWorkbook;
            }

            set
            {
                Config.Mode = SpreadsheetModeEnum.NewWorkbook;

                // Update bindings, no broadcast
                RaisePropertyChanged(IsNewWorkbookPropertyName);
                RaisePropertyChanged(IsCreatedByMacroPropertyName);
                RaisePropertyChanged(IsExistingWorkbookPropertyName);

            }
        }


        /// <summary>
        /// The <see cref="IsExistingWorkbook" /> property's name.
        /// </summary>
        public const string IsExistingWorkbookPropertyName = "IsExistingWorkbook";

        /// <summary>
        /// Gets the IsExistingWorkbook property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsExistingWorkbook
        {
            get
            {
                return Config.Mode == SpreadsheetModeEnum.OpenExisitng;
            }

            set
            {
                Config.Mode = SpreadsheetModeEnum.OpenExisitng;

                // Update bindings, no broadcast
                RaisePropertyChanged(IsExistingWorkbookPropertyName);
                RaisePropertyChanged(IsCreatedByMacroPropertyName);
                RaisePropertyChanged(IsNewWorkbookPropertyName);

            }
        }

        /// <summary>
        /// The <see cref="FilePath" /> property's name.
        /// </summary>
        public const string FilePathPropertyName = "FilePath";

        private String _filePath = null;

        /// <summary>
        /// Gets the FilePath property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public String FilePath
        {
            get
            {
                return _filePath;
            }

            set
            {
                if (_filePath == value)
                {
                    return;
                }
                _filePath = value;


                // Update bindings, no broadcast
                RaisePropertyChanged(FilePathPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="SelectedScenario" /> property's name.
        /// </summary>
        public const string SelectedScenarioPropertyName = "SelectedScenario";

        private const string DisplayNameProperty = "DisplayName";

        private ScenarioViewModel _selectedScenario = null;

        /// <summary>
        /// Gets the SelectedScenario property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ScenarioViewModel SelectedScenario
        {
            get
            {
                return _selectedScenario;
            }

            set
            {
                if (_selectedScenario == value)
                {
                    return;
                }

                var oldValue = _selectedScenario;
                _selectedScenario = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(SelectedScenarioPropertyName);
            }
        }
        
        /// <summary>
        /// Gets the Scenarios property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<ScenarioViewModel> Scenarios
        {
            get
            {
                if(!_lazyLoaded)
                {
                    LoadScenarios();
                }
                return _scenarios;
            }

            set
            {
                if (_scenarios == value)
                {
                    return;
                }

                var oldValue = _scenarios;
                _scenarios = value;


                // Update bindings, no broadcast
                RaisePropertyChanged(ScenariosPropertyName);

            }
        }

        private void LoadScenarios()
        {
            _lazyLoaded = true;
            _configService.GetScenariosForSheet(Config, (result, ex) =>
                                                            {
                                                                if(result == null)
                                                                {
                                                                    throw new ApplicationException("Could not load scenarios for sheet " + Config.Name + ".", ex);
                                                                }
                                                                ViewModelLocator viewModelLocator = ViewModelLocator.Instance;
                                                                
                                                                Scenarios = new ObservableCollection<ScenarioViewModel>(from s in result
                                                                            select viewModelLocator.GetViewModel<ScenarioViewModel>(new Dictionary<string, object>(){{"scenario", s}}));
                                                                if(Scenarios.Any())
                                                                {
                                                                    SelectedScenario = Scenarios.First();
                                                                    
                                                                } else
                                                                {
                                                                    SelectedScenario = null;
                                                                }
                                                            });
        }

        #endregion Public Properties




        #region Constructors

        /// <summary>
        /// Initializes a new instance of the TestGroupViewModel class.
        /// </summary>
        public SheetConfigViewModel(SheetConfig sheetConfig, ITestConfigService configService)
        {
            _configService = configService;
            Config = sheetConfig;
        }

        #endregion Constructors


        #region Commands

        private ICommand _saveAndEnd;

        public ICommand SaveAndEnd
        {
            get
            {
                if(_saveAndEnd == null)
                {
                    _saveAndEnd = new RelayCommand(()=>
                                                       {
                                                           ViewModelLocator.Instance.Main.OverlayViewModel = null;
                                                       });
                }
                return _saveAndEnd;
            }
        }

        private ICommand _selectWorkbook;

        public ICommand SelectWorkbook
        {
            get
            {
                if(_selectWorkbook == null)
                {
                    _selectWorkbook = new RelayCommand(() =>
                                                           {
                                                               
                                                           }, ()=> IsExistingWorkbook);
                }
                return _selectWorkbook;
            }
        }

        #endregion Commands

        ////public override void Cleanup()
        ////{
        ////    // Clean own resources if needed

        ////    base.Cleanup();
        ////}
    }
}